package com.zp.demo.repush.aop;

import com.zp.demo.repush.RePushUtils;
import com.zp.demo.repush.anno.RePushSuccessOnceAnno;
import com.zp.demo.repush.service.func.IsSucessFunc;
import com.zp.demo.repush.service.func.ReSubmitResultFunc;
import com.zp.demo.repush.service.defined.DefinedRePushFitter;
import com.zp.demo.repush.vo.RePushProperties;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.lang.reflect.Method;

@Component
@Aspect
@Log4j2
public class RePushSuccessOnceAop {
    @Autowired
    private DefinedRePushFitter rePushFitter;
    @Autowired
    private RePushProperties rePushProperties;
    @Pointcut("@annotation(onceAnno)")
    public void repushSuccessAno(RePushSuccessOnceAnno onceAnno) {
    }
    @Around("repushSuccessAno(onceAnno)")
    public Object around(ProceedingJoinPoint pjp, RePushSuccessOnceAnno onceAnno) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        String key = this.getKey(methodSignature,pjp.getArgs());
        // 先判断是否已经成功
        boolean isFillter = rePushFitter.checkSuccessOnes(key, rePushProperties.getSucessOnceSleepTime());
        if(isFillter){
            Object result = pjp.proceed();
            Class<?> isOkFun = onceAnno.isOkClazz();
            IsSucessFunc isSucessFunc = (IsSucessFunc) isOkFun.newInstance();
            boolean isTrue = isSucessFunc.isSucess(result);
            // 执行继续异常 移除锁
            if(!isTrue){
                rePushFitter.removeCheckSuccess(key);
            }
            return result;
        }else{
            // 重复提交，正在被提交中
            Assert.notNull(onceAnno.reSubmitResult(), "未设置 重复提交的异常返回结果：ReSubmitResultFunc 未传入值");
            Class<?> reSubmitResult = onceAnno.reSubmitResult();
            ReSubmitResultFunc reSubmitResultFunc = (ReSubmitResultFunc)reSubmitResult.newInstance();
            return reSubmitResultFunc.reSubmitResult();
        }
    }
    public String getKey( MethodSignature methodSignature,Object[] args ){
        Class<?> clazz = methodSignature.getDeclaringType();
        Method targetMethod = methodSignature.getMethod();
        String methodId = RePushUtils.getMethodId(clazz, targetMethod);
        // 获取app有待改进
        String key = RePushUtils.generKey(methodId,args);
        return key;
    }

}
